
#ifndef __MY_SERVER__
#define __MY_SERVER__

#include "data.hpp"
#include "httplib.h"

namespace vod_ns
{
    const std::string wwwroot = "./www";
    const std::string video_root = "/video/";
    const std::string image_root = "/image/";

    TableVideo *tb_video = nullptr;

    class Server
    {
    private:
        static void Insert(const httplib::Request &req, httplib::Response &rsp)
        {
            // 检查客户端上传的数据
            if (req.has_file("name") == false ||
                req.has_file("info") == false ||
                req.has_file("video") == false ||
                req.has_file("image") == false)
            {
                rsp.status = 400;
                rsp.body = R"({"result":false, "reason":"上传的数据信息错误"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }

            httplib::MultipartFormData name = req.get_file_value("name");   // 视频名称
            httplib::MultipartFormData info = req.get_file_value("info");   // 视频简介
            httplib::MultipartFormData video = req.get_file_value("video"); // 视频文件
            httplib::MultipartFormData image = req.get_file_value("image"); // 图片文件

            std::string video_name = name.content;
            std::string video_info = info.content;
            std::string video_path = wwwroot + video_root + video_name + video.filename;
            std::string image_path = wwwroot + image_root + video_name + image.filename;

            // 视频存储
            if (FileUtil(video_path).SetContent(video.content) == false)
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"视频文件存储失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }
            // 图片存储
            if (FileUtil(image_path).SetContent(image.content) == false)
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"图片文件存储失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }
            // 数据库管理信息存储
            Json::Value val;
            val["name"] = video_name;
            val["info"] = video_info;
            val["video"] = video_root + video_name + video.filename;
            val["image"] = image_root + video_name + image.filename;
            if (tb_video->Insert(val) == false)
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"数据库新增数据失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }
            rsp.set_redirect("/index.html", 303);
            return;
        }

        static void Update(const httplib::Request &req, httplib::Response &rsp)
        {
            // 获取要修改的视频信息
            int video_id = std::stoi(req.matches[1]);
            Json::Value video;
            if (JsonUtil::Deserialize(req.body, &video) == false)
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"新视频格式解析失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }
            if (tb_video->Update(video_id, video) == false)
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"数据库修改数据失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }
            return;
        }

        static void Delete(const httplib::Request &req, httplib::Response &rsp)
        {
            // 获取要删除的视频 ID
            int video_id = std::stoi(req.matches[1]);
            // 删除视频以及图片文件
            Json::Value video;
            if (tb_video->SelectOne(video_id, &video) == false)
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"查无此视频信息"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }
            std::string video_path = wwwroot + video["video"].asString();
            std::string image_path = wwwroot + video["image"].asString();
            remove(video_path.c_str());
            remove(image_path.c_str());
            // 删除数据库信息
            if (tb_video->Delete(video_id) == false)
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"数据库信息删除失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }
            return;
        }

        static void SelectOne(const httplib::Request &req, httplib::Response &rsp)
        {
            // 获取视频 ID
            int video_id = std::stoi(req.matches[1]);
            // 在数据库中查询指定视频信息
            Json::Value video;
            if (tb_video->SelectOne(video_id, &video) == false)
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"查询指定视频信息失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }
            // 组织响应正文 --> Json 格式的字符串
            JsonUtil::Serialize(video, &rsp.body);
            std::cout << rsp.body << std::endl;
            rsp.set_header("Content-Type", "application/json");
            return;
        }

        static void SelectAll(const httplib::Request &req, httplib::Response &rsp)
        {
            bool select_flag = true;
            std::string search_key;
            if (req.has_param("search") == true)
            {
                std::cout << "search" << std::endl;
                select_flag = false; // 模糊匹配
                search_key = req.get_param_value("search");
            }
            Json::Value videos;
            if (select_flag)
            {
                if (tb_video->SelectAll(&videos) == false)
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"查询指定视频信息失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }
            }
            else
            {
                std::cout << "haha" << std::endl;
                if (tb_video->SelectLike(search_key, &videos) == false)
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"查询指定视频信息失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }
            }
            JsonUtil::Serialize(videos, &rsp.body);
            std::cout << rsp.body << std::endl;
            rsp.set_header("Content-Type", "application/json");
            return;
        }

    public:
        Server(in_port_t port)
            : _port(port) {}

        bool RunModule()
        {
            // 初始化操作
            // 初始化数据管理模块，创建指定目录
            tb_video = new TableVideo();
            FileUtil(wwwroot).CreateDirectory();
            std::string video_real_path = wwwroot + video_root;
            FileUtil(video_real_path).CreateDirectory();
            std::string image_real_path = wwwroot + image_root;
            FileUtil(image_real_path).CreateDirectory();
            // 搭建 HTTP 服务器
            // 设置静态资源根目录
            _srv.set_mount_point("/", wwwroot);
            // 接口设计，添加 请求-处理函数 映射关系
            _srv.Post("/video", Server::Insert);
            _srv.Delete("/video/(\\d+)", Server::Delete);
            _srv.Put("/video/(\\d+)", Server::Update);
            _srv.Get("/video", Server::SelectAll);
            _srv.Get("/video/(\\d+)", Server::SelectOne);
            // 启动服务器
            _srv.listen("0.0.0.0", _port);
            return true;
        }

    private:
        in_port_t _port;
        httplib::Server _srv;
    };
}

#endif